package cn.datacare.wechat.common.user.service.impl;

import cn.datacare.wechat.common.common.utils.AssertUtil;
import cn.datacare.wechat.common.common.utils.oss.MinIOTemplate;
import cn.datacare.wechat.common.common.utils.oss.OssProperties;
import cn.datacare.wechat.common.common.utils.oss.domain.OssReq;
import cn.datacare.wechat.common.common.utils.oss.domain.OssResp;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.file.FileNameUtil;
import cn.hutool.core.util.StrUtil;
import cn.datacare.wechat.common.user.domain.enums.OssSceneEnum;
import cn.datacare.wechat.common.user.domain.vo.request.oss.UploadUrlReq;
import cn.datacare.wechat.common.user.service.OssService;
import com.aliyun.oss.*;
import com.aliyun.oss.model.GeneratePresignedUrlRequest;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.UnsupportedEncodingException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

/**
 * Description:
* @author: Evan
 * Date: 2023-06-20
 */
@Slf4j
@Service
public class OssServiceImpl implements OssService {

    @Autowired
    MinIOTemplate minIOTemplate;

    private  final OssProperties properties;

    public OssServiceImpl(OssProperties properties) {
        this.properties = properties;
    }

    @Override
    public OssResp getUploadUrl(Long uid, UploadUrlReq req) {
        OssSceneEnum sceneEnum = OssSceneEnum.of(req.getScene());
        AssertUtil.isNotEmpty(sceneEnum, "场景有误");
        OssReq ossReq = OssReq.builder()
                .fileName(req.getFileName())
                .filePath(sceneEnum.getPath())
                .contentType(req.getContentType())
                .uid(uid)
                .build();
        try {
            return  this.uploadFile(ossReq);
        } catch (URISyntaxException e) {
            throw new RuntimeException(e);
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
        // return minIOTemplate.getPreSignedObjectUrl(ossReq);
    }

    private String getDownloadUrl(String bucket, String pathFile) {
        return "http://yunquchat.oss-cn-shanghai.aliyuncs.com" + StrUtil.SLASH+ pathFile;
    }

    public String generateAutoPath(OssReq req) {
        String uid = Optional.ofNullable(req.getUid()).map(String::valueOf).orElse("000000");
        cn.hutool.core.lang.UUID uuid = cn.hutool.core.lang.UUID.fastUUID();
        String suffix = FileNameUtil.getSuffix(req.getFileName());
        String yearAndMonth = DateUtil.format(new Date(), DatePattern.NORM_MONTH_PATTERN);
        return req.getFilePath() + StrUtil.SLASH + yearAndMonth + StrUtil.SLASH + uid + StrUtil.SLASH + uuid + StrUtil.DOT + suffix;
    }

    private OssResp uploadFile( OssReq req) throws URISyntaxException, UnsupportedEncodingException {
        String absolutePath = req.isAutoPath() ? generateAutoPath(req) : req.getFilePath() + StrUtil.SLASH + req.getFileName();
        absolutePath=absolutePath.replaceFirst("/","");
        log.info("absolutePath:{}",absolutePath);
        OSS ossClient = new OSSClientBuilder()
                .build(properties.getEndpoint(), properties.getAccessKey(), properties.getSecretKey());
        Map<String, String> headers = new HashMap<>(2);
        if(StringUtils.isEmpty(req.getContentType())) {
            headers.put("Content-Type", "audio/wav");
        }else{
            headers.put("Content-Type", req.getContentType());
        }
        //headers.put("Content-Type","image/jpeg");
        Map<String, String> userMetadata = new HashMap<>();
        URL signedUrl = null;
        try{
            Date expiration = new Date(System.currentTimeMillis() + 3600 * 1000L);

            GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(properties.getBucketName(), absolutePath, HttpMethod.PUT);
            request.setExpiration(expiration);
            // 将请求头加入到request中。
            request.setHeaders(headers);
            // 添加用户自定义元信息。
            request.setUserMetadata(userMetadata);
            // 通过HTTP PUT请求生成签名URL。
            signedUrl = ossClient.generatePresignedUrl(request);
            log.info("signedUrl:{}",signedUrl);
        }catch (OSSException e){
            log.error(e.getErrorMessage(),e);
        }catch (ClientException e){
            log.error(e.getErrorMessage(),e);
        }finally {
            if(ossClient!=null){
                ossClient.shutdown();
            }
        }
        return OssResp.builder()
                .uploadUrl(signedUrl.toString())
                .downloadUrl(getDownloadUrl(properties.getBucketName(), absolutePath))
                .build();

    }
}
